<?php

class Node {
    protected static $tag = 'html';
    protected $attr;
    protected $data = '';
    private $children = array();
    
    public function __construct($attr = null) { $this->attr = $attr; }

    protected function add_child($child) { $this->children[] = $child; }

    public function render_html() {
        $tag = static::$tag;
        $result = '<'.$tag.(isset($this->attr) ? ' '.$this->attr : '').'>'.$this->data;
        foreach ($this->children as $child) {
            $result .= $child->render_html();
        }
        $result .= '</'.$tag.'>';
        return $result;
    }
}

class Datum extends Node {
    protected static $tag = 'td';
    
    public function __construct($data, $attr = null) {
        parent::__construct($attr);
        $this->data = $data;
    }
}
    
class Row extends Node {
    protected static$tag = 'tr';
    
    public function __construct($row, $attr = null) {
        parent::__construct($attr);
        foreach ($row as $datum) {
            $this->add_child(new Datum($datum));
        }
    }
}

class Header extends Datum {
    protected static $tag = 'th';
} 

class Table extends Node {
    protected static $tag = 'table';
    
    public function __construct($header,$rows, $attr = null) {
        parent::__construct($attr);
        foreach ($header as $title) {
            $this->add_child(new Header($title));
        }
        foreach ($rows as $row) {
            $this->add_child(new Row($row));
        }
    }
}

$th = ['ONE','TWO','THREE','FOUR','FIVE'];
$tb = [ ['this','is','the','first','row'],
        ['here','is','the','second','row'],
        ['and','now','the','third','row!'] ];

$table = new Table($th,$tb, 'id="table1" border="1"');
echo '<pre>'.$table->render_html().'</pre>';

echo '<pre>'.eviltable($th,$tb, 'border="1"').'</pre>';

function eviltable($th,$tb, $attr) {
    $result = '<table'.(isset($attr) ? ' '.$attr : '').'>';
    foreach ($th as $head) {
        $result .= '<th>'.$head.'</th>';
    }
    foreach ($tb as $row) {
        $result .= '<tr>';
        foreach ($row as $datum) {
            $result .= "<td>$datum</td>";
        }
        $result .= '</tr>';
    }
    $result .= '</table>';
    return $result;
}


?>